/*
 +-----------------------------------------------------------------------------------------------+
 | Project : UKAPI
 +-----------------------------------------------------------------------------------------------+
 | Project Description : Universal & Kernel API
 +-----------------------------------------------------------------------------------------------+
 | File Description :
 |   Task
 |                                                 
 +-----------------------------------------------------------------------------------------------+
 | Licence : MIT Licence
 +-----------------------------------------------------------------------------------------------+
 | Copyright (c) 2006 Olivier Vanhoucke
 | 
 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 | and associated documentation files (the "Software"), to deal in the Software without 
 | restriction, including without limitation the rights to use, copy, modify, merge, publish, 
 | distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the 
 | Software is furnished to do so, subject to the following conditions:
 | 
 | The above copyright notice and this permission notice shall be included in all copies or 
 | substantial portions of the Software.
 | 
 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
 | BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 +-----------------------------------------------------------------------------------------------+
*/

#ifndef __UKAPI_KERNEL_TASK__
#define __UKAPI_KERNEL_TASK__

typedef enum
{
	task_state_running_e,
	task_state_ready_e,
	task_state_suspended_e,
	task_state_stopped_e,
} task_state_t;

typedef struct
{
	ppointer_t	args;
	size_t		argc;
} task_parameter_t, * ptask_parameter_t;

//#if SCHEDULER_TYPE == SCHEDULER_TYPE_TINY_PRIORITY
//		
//#endif /* SCHEDULER_TYPE */

#define pcpu_context_t void * // TODO

typedef struct
{
	/* Hardware Context Infos */
	pcpu_context_t context;

	/* Task Infos */
	dword_t (*pfnTask)( ptask_parameter_t arg ); // TODO : change type !
	ptask_parameter_t	task_arg;
	task_state_t		state;
	dword_t				task_id;
	//dword_t			base_quantum_time; // time slice + quantum
	dword_t				priority;
	dword_t				counter;
	dword_t				exit_code;

	/* Stack Infos */
	pointer_t		stack_address;
	dword_t			stack_size;
	
	/* Heap Infos */
	pointer_t		heap_address;
	dword_t			heap_size;

	/* Stats Infos */
	//dword_t			start_time;
	//dword_t			wakeup_time;
	//dword_t			running_time;

	/* Rights Infos */

	/* Event Infos */
	//list_t			event_list; // state, callback
	dword_t		events;
	callback_t	pfnEventCallback[32];

	/* File System Infos ? */

	/* Sublayer Infos */
#if CPU_ARCHITECTURE == CPU_ARCHITECTURE_WIN32
	HANDLE				handle_task;
	bool_t				update_priority;
	bool_t				new;
#elif CPU_ARCHITECTURE == CPU_ARCHITECTURE_POSIX
	pthread_t			handle_task;
#else
	//int				handle_task;		
#endif

} task_t, * ptask_t;

#ifdef __cplusplus
	extern "C" {
#endif /* __cplusplus */

result_t task_create( ptask_t pTask, task_state_t initial_state, dword_t (*pfnTask)( ptask_parameter_t arg ), ptask_parameter_t arg );
result_t task_start( ptask_t pTask );
result_t task_set_priority( ptask_t pTask, dword_t new_priority );
dword_t	 task_get_priority( ptask_t pTask );
result_t task_suspend( ptask_t pTask );
result_t task_sleep( dword_t millisecond );
result_t task_resume( ptask_t pTask );
result_t task_destroy( ptask_t pTask, dword_t exit_code );

ptask_t task_current();

// result_t task_switch( ptask_t pcurrent, ptask_t pnew ) // for kernel, how to implement CPU Specific ???

/* Primitives for sublayers */
result_t _task_create( ptask_t pTask );
result_t _task_start( ptask_t pTask );
result_t _task_suspend( ptask_t pTask );
result_t _task_sleep( dword_t millisecond );
result_t _task_resume( ptask_t pTask );
result_t _task_destroy( ptask_t pTask );

#ifdef __cplusplus
	}
#endif /* __cplusplus */

#endif /* __UKAPI_KERNEL_TASK__ */